#include "user.h"
#include "database.h"
#include "log.h"

// 辅助函数示例实现  发送 接收
void send_msg_to_server(int fd, MSG msg) {
    if (send(fd, &msg, sizeof(MSG), 0) < 0) {
        perror("发送消息失败");
    }
}

void receive_msg_from_server(int fd, MSG response) {
    ssize_t bytes_received = recv(fd, &response, sizeof(MSG), 0);
    if (bytes_received <= 0) {
        if (bytes_received == 0) {
            printf("连接已关闭。\n");
        } else {
            perror("接收消息失败");
        }
    }
}

// 安全地转义列名（简单示例，实际情况可能更复杂）
void escape_column_name(char *dest, const char *src) {
    while (*src) {
        if (*src == '\'') {
            strcat(dest, "''"); // 替换单引号为两个单引号
        } else {
            strncat(dest, src, 1);
        }
        src++;
    }
}

// 用户 查看 群聊列表
void view_merchant_group(int fd,MSG msg){
    // 查询char表中所有 user_or_merchant(不包括这个) 后面的列名作为群聊名称
    // 查询所有表 并找到 表头 返回值第 11后的列
    
    char query[] = "SELECT * FROM char;";
    RET ret = database_query(db ,query );

    printdatabase_headtab(ret);

    if(ret.col > 10){
        printf("存在商家创建的群聊\n");
        printf("会发送%d个群过去\n",ret.col-10);
            // 构建订单信息字符串并逐条发送给客户端
        for (int i = 11; i < ret.col; i++) {
            // 每次构建单个订单的信息字符串
            char orderInfo[256] = "";
            snprintf(orderInfo, sizeof(orderInfo),
                    "群名:%s",
                    ret.result[i]);
            printf("查询到的群有%s\n",ret.result[i]);

            // 发送单个订单信息给客户端
            MSG response = { .type = _yes };
            strncpy(response.data, orderInfo, sizeof(response.data) - 1);
            response.data[sizeof(response.data) - 1] = '\0'; // 确保字符串终止符
            send_msg_to_server(fd, response);
        }

    printf("循环结束l\n");

    // 发送结束信号 over 给客户端
    MSG endMsg = { .type = over };

    char orderInfoo[256] = "";
            snprintf(orderInfoo, sizeof(orderInfoo),
                    "这是over信号"
                    );
    strncpy(endMsg.data, orderInfoo, sizeof(endMsg.data) - 1);
    endMsg.data[sizeof(endMsg.data) - 1] = '\0'; // 确保字符串终止符
                   
    send_msg_to_server(fd, endMsg);
    printf("已经发送over信号\n");
        
    }
    else {
        // 发送结束信号 over 给客户端
    MSG endMsg = { .type = _no };
    send_msg_to_server(fd, endMsg);
    }

}

// 添加新列到现有的 char 表
void add_group_column(sqlite3 *db, const char *group_name) {
    char escaped_group_name[65]; // 确保有足够的空间容纳转义后的群名
    escaped_group_name[0] = '\0'; // 初始化为空字符串
    escape_column_name(escaped_group_name, group_name);

    // 构建 ALTER TABLE 语句
    char alterSql[256];
    snprintf(alterSql, sizeof(alterSql),
             "ALTER TABLE `char` ADD COLUMN `%s` VARCHAR(16);",
             escaped_group_name);

    // 执行 ALTER TABLE 语句
    exec_sql(db, alterSql);
}

// 加入商家活动群
void join_merchant_group(int fd ,MSG msg){
    SC * pSC = (SC *)msg.data;
    printf("用户%s 发送 加入 %s 群聊的 请求\n",pSC->self,pSC->dest);
    // 构建插入语句  将商家设置为创建者 标识 1
    char insertSql[512];
    snprintf(insertSql, sizeof(insertSql),
             "INSERT INTO char (user_one_name,    private_char,\
              group_char_system, merchant_shop_name, shop_id, \
              user_or_merchant, '%s') "\
             "VALUES ('用户%s',    'no', 'yes', '', '', 'user', 9);",
             pSC->dest, pSC->self); // 假设 currentLoginUserName 是当前登录的商家用户名

    // 执行插入语句
    exec_sql(db, insertSql);
    // 检查插入是否成功
    int changes = sqlite3_changes(db);
    if (changes > 0) {
        // 成功创建群聊，返回成功消息
        MSG resp_msg = {0};
        resp_msg.type = _yes;
        strncpy(resp_msg.data, "加入群聊成功！", sizeof(resp_msg.data) - 1);
        resp_msg.data[sizeof(resp_msg.data) - 1] = '\0';
        send(fd, &resp_msg, sizeof(resp_msg), 0);
    } else {
        // 创建群聊失败，返回错误消息
        MSG resp_msg = {0};
        resp_msg.type = _no;
        strncpy(resp_msg.data, "加入群聊失败，请重试。", sizeof(resp_msg.data) - 1);
        resp_msg.data[sizeof(resp_msg.data) - 1] = '\0';
        send(fd, &resp_msg, sizeof(resp_msg), 0);
    }

}

/* // 用户 开始 群聊 
void insert_merchant_group(int fd,MSG msg){
    //保存在群中用户的 用户名数组 
    char save_user_name[1024][128];
    //保存 群中用户 的 套接字
   int save_user_fd[1024];

    SC * pSC = (SC *)msg.data;
    printf("用户%s 在%s 群 发送  %s  消息\n",pSC->self,pSC->dest,pSC->text);

    //先在char 表中 找到对应的 群 并且 下标 为 9
     
    char queryUserSql[256];
    snprintf(queryUserSql, sizeof(queryUserSql),\
     "SELECT * FROM char WHERE '%s'=9;", pSC->dest );
    RET ret = database_query(db, queryUserSql);
    DEBUG("%s",queryUserSql);
    DEBUG("查找群聊下标为9的用户");
    printdatabase_headtab(ret);
    printdatabase(ret);
    DEBUG("第一个群聊用户 下标 为9 查询到的 %s",ret.result[ret.col+12]);
if(ret.row > 0){
     //用  个数组保存   用户 
    for(int i = ret.col; i< ret.row ; i++){

        DEBUG("%s",ret.result[ret.col]);

        memcpy(save_user_name[i] , ret.result[i] ,strlen(ret.result[i]) + 1);

        //解析用户名 例：用户1
        char a[128];
        sscanf(save_user_name[i] , "用户%s",a);

        //从用户表中找 套接字 并循环发送消息
        char  Sql[256];
        snprintf( Sql, sizeof( Sql),\
        "SELECT user_fd FROM people WHERE name ='%s';", a);
        ret = database_query(db,  Sql);
        printdatabase_headtab(ret);
        printdatabase(ret);

         if (ret.row > 0) {
            // 假设 ret.result[0] 是一个整数，直接赋值给 save_user_fd[i]
            save_user_fd[i] = atoi(ret.result[0]);
            // 发送消息
            if (save_user_fd[i] > 2) {
                send(save_user_fd[i], pSC->text, strlen(pSC->text) + 1, 0);
            }
        }
    
    }
}
    
    
     
}
 */
// 用户 开始 群聊 
void insert_merchant_group(int fd,MSG msg){
    //保存在群中用户的 用户名数组 
    char save_user_name[1024][128];
    //保存 群中用户 的 套接字
   int save_user_fd;

    SC * pSC = (SC *)msg.data;
    printf("用户%s 在%s 群 发送  %s  消息\n",pSC->self,pSC->dest,pSC->text);

    //先在char 表中 找到对应的 群 并且 下标 为 9
     
    char queryUserSql[256];
    snprintf(queryUserSql, sizeof(queryUserSql),\
     "SELECT user_one_name FROM char WHERE %s=9;", pSC->dest );
    RET ret = database_query(db, queryUserSql);
    DEBUG("%s",queryUserSql);
    DEBUG("查找群聊下标为9的用户");
    printdatabase_headtab(ret);
    printdatabase(ret);
    DEBUG("第一个群聊用户 下标 为9 查询到的 %s",ret.result[ret.col]);

    printf("循环次数 %d\n",ret.row);
     //用  个数组保存   用户 
    for(int i = ret.col; i<= ret.row ; i++){

        DEBUG("%s",ret.result[ret.col]);

        memcpy(save_user_name[i] , ret.result[i] ,strlen(ret.result[i]) + 1);

        //解析用户名 例：用户1
        char a[128];
        //sscanf(save_user_name[i] , "用户%s",a);
        //sscanf(save_user_name[i], "%*[^%s]%s", "用户", a);
        char *username = save_user_name[i];
        if (strncmp(username, "用户", 2) == 0) {
            username += 2*3; // 跳过前缀 "用户"
            sscanf(username, "%s", a);
        }
        printf("在群里面的 用户名 是  %s\n",a);

        //从用户表中找 套接字 并循环发送消息
        char  Sql[256];
        snprintf( Sql, sizeof( Sql),\
        "SELECT user_fd FROM people WHERE name =%s;", a);
        RET rret = database_query(db,  Sql);
        printdatabase_headtab(rret);
        printdatabase(rret);

         if (rret.row > 0) {
            // 假设 ret.result[0] 是一个整数，直接赋值给 save_user_fd[i]
            save_user_fd = atoi(rret.result[rret.col]);
            printf(" fd  是 %d\n",save_user_fd);
            // 发送消息
            if (save_user_fd > 2) {
                printf("发送成功\n");
               
// 发送响应给客户端
    MSG resp_msg = {0};
    resp_msg.type = _insert_merchant_group;
    //memcpy(resp_msg.data ,pSC,sizeof(pSC));
    printf(" 发送的数据是%s\n",pSC->text);
    memcpy(resp_msg.data ,pSC->text,sizeof(pSC));
    send(save_user_fd, &resp_msg, sizeof(resp_msg), 0);
                //send(save_user_fd , &msg, sizeof(msg), 0);
            }
        }
    
    }

    
    
     
}

//商家创建群聊
void server_merchant_creat_group(int fd,MSG msg){
    
    SC * pSC = (SC *)msg.data;
    printf("商家%s 发送 建立 %s 群聊的 请求\n",pSC->self,pSC->dest);

    
    
    //修改表  添加一个列
    char sqql[256];
    sprintf(sqql, "ALTER TABLE char ADD '%s' varchar(64)",pSC->dest);
    exec_sql(db , sqql);
    
     // 构建插入语句 9 表示在群中
    char insertSqll[512];
    snprintf(insertSqll, sizeof(insertSqll),
             "INSERT INTO char (user_one_name,    private_char,\
              group_char_system, merchant_shop_name, shop_id, \
              user_or_merchant, '%s') "\
             "VALUES ('商家%s',    'no', 'yes', '', '', 'merchant', 9);",
             pSC->dest, pSC->self); // 假设 currentLoginUserName 是当前登录的商家用户名

    // 执行插入语句
    exec_sql(db, insertSqll);

    // 构建插入语句  将商家设置为创建者 标识 1
    char insertSql[512];
    snprintf(insertSql, sizeof(insertSql),
             "INSERT INTO char (user_one_name,    private_char,\
              group_char_system, merchant_shop_name, shop_id, \
              user_or_merchant, '%s') "\
             "VALUES ('商家%s',    'no', 'yes', '', '', 'merchant', 1);",
             pSC->dest, currentLoginUserName); // 假设 currentLoginUserName 是当前登录的商家用户名

    // 执行插入语句
    exec_sql(db, insertSql);
    // 检查插入是否成功
    int changes = sqlite3_changes(db);
    if (changes > 0) {
        // 成功创建群聊，返回成功消息
        MSG resp_msg = {0};
        resp_msg.type = _yes;
        strncpy(resp_msg.data, "群聊创建成功！", sizeof(resp_msg.data) - 1);
        resp_msg.data[sizeof(resp_msg.data) - 1] = '\0';
        send(fd, &resp_msg, sizeof(resp_msg), 0);
    } else {
        // 创建群聊失败，返回错误消息
        MSG resp_msg = {0};
        resp_msg.type = _no;
        strncpy(resp_msg.data, "群聊创建失败，请重试。", sizeof(resp_msg.data) - 1);
        resp_msg.data[sizeof(resp_msg.data) - 1] = '\0';
        send(fd, &resp_msg, sizeof(resp_msg), 0);
    }

}


//顾客私聊商家
void msgChar(int fd,MSG msg){
    SC * pSC = (SC *)msg.data;
    //通过 用户名 遍历 用户表  找到套接字
    char queryUserSql[256];
    snprintf(queryUserSql, sizeof(queryUserSql),\
     "SELECT merchant_fd FROM merchant WHERE name ='%s';", pSC->dest);
    RET ret = database_query(db, queryUserSql);
    printf(" 正在查询商家在不在线\n");
    printdatabase(ret);
    printf("有查到%d行\n",ret.row);


    // 有套接字就说明 在线 就 发送过去
    if(ret.row > 0){
        printf("有这个商家商家在\n");
         msg.type = _msgChar ;
        int ffd = atoi(ret.result[ret.col]);
        printf("商家的套接字是 %d  %s\n",ffd,ret.result[ret.col]);
       
        if(ffd>2){
            printf("商家在线\n");
            send(ffd,&msg,sizeof(msg),0);
            return;
        }

        //否则就存入 数据库中
        printf("没有找到聊天的对象，说明对方没有登录，可以把聊天记录存入到一个表格中，每个客户端段登录的时候，都会去查询这个表格，看看里面有没有自己的包裹\n");
        char sql[256];
        sprintf(sql,"INSERT INTO char(user_one_name,  user_two_name,  \
        char_data, read_state,private_char) VALUES ('%s','商家%s','%s','no','yes');",
        pSC->self,pSC->dest,pSC->text);
        printf("%s\n",sql);
        exec_sql(db, sql);
        
        return ;
    }else if(ret.row == 0){
        printf("没有这个商家\n");
        return ;
    }

    
}

//商家私聊顾客
void merchant_guke_chat(int fd,MSG msg){
    SC * pSC = (SC *)msg.data;
    //通过 用户名 遍历 用户表  找到套接字
    char queryUserSql[256];
    snprintf(queryUserSql, sizeof(queryUserSql),\
     "SELECT user_fd FROM people WHERE name ='%s';", pSC->dest);
    RET ret = database_query(db, queryUserSql);
    
    // 有套接字就说明 在线 就 发送过去
    if(ret.row > 0){
        msg.type = _msgChar ;
        int ffd = atoi(ret.result[ret.col]);
        send(ffd,&msg,sizeof(msg),0);
        return ;
    }

    //否则就存入 数据库中
    printf("没有找到聊天的对象，说明对方没有登录，可以把聊天记录存入到一个表格中，每个客户端段登录的时候，都会去查询这个表格，看看里面有没有自己的包裹\n");
     char sql[256];
     sprintf(sql,"INSERT INTO char(user_one_name,  user_two_name,  \
       char_data, read_state,private_char) VALUES ('商家%s','%s','%s','no','yes');",
     pSC->self,pSC->dest,pSC->text);
     printf("%s\n",sql);
     exec_sql(db, sql);
}

// 在线用户的群聊 
void _groupChat(int fd , MSG m1)
{
     //遍历登录数组
     for (size_t i = 0; i < login_count; i++)
     {
          send(fdArr[i],&m1,sizeof(m1),0);//把消息转发出去
     }
     
}

// 用户私聊
void _singleChat(int fd , MSG m1){
    SC * pSC = (SC *)m1.data;

     for (size_t i = 0; i < login_count; i++)
     {
          //查找对方的名字
          if(strcmp(pSC->dest,nameArr[i]) == 0)
          {
               send(fdArr[i],&m1,sizeof(m1),0);//把消息转发给下标为i的套接字
               return;
          }
     }
     printf("没有找到聊天的对象，说明对方没有登录，可以把聊天记录存入到一个表格中，每个客户端段登录的时候，都会去查询这个表格，看看里面有没有自己的包裹\n");
     char sql[256];
     sprintf(sql,"INSERT INTO char(user_one_name,  user_two_name,  \
       char_data, read_state,private_char) VALUES ('%s','%s','%s','no','yes');",
     pSC->self,pSC->dest,pSC->text);
     printf("%s\n",sql);
     exec_sql(db, sql);
}

// 用户 查看未读消息
void view_chat_noread(int fd,MSG msg){
    printf("%s\n",msg.data);
    //在数据库中查找 第二个用户名 为这个数据  私聊 并且 状态是未读 的
     char user_two_name[64];
    strncpy(user_two_name, msg.data, sizeof(user_two_name) - 1);
    user_two_name[sizeof(user_two_name) - 1] = '\0';
    // 构建查询语句  查私聊
    char querySql[512];
    snprintf(querySql, sizeof(querySql),
             "SELECT user_one_name, char_data FROM char "
             "WHERE user_two_name='%s' AND private_char='yes' AND read_state='no';",
             user_two_name);
    // 执行查询并处理结果
    RET ret = database_query(db, querySql);
    DEBUG("用户查看有没有未读消息");
    printdatabase(ret);
     int siliao = 0;
    if (ret.row > 0 && ret.col > 0) {
        siliao = ret.row;
    }
    // 构建查询语句  查群聊
    char qquerySql[512];
    snprintf(qquerySql, sizeof(qquerySql),
             "SELECT user_one_name, char_data FROM char "
             "WHERE user_two_name='%s' AND group_char_system='yes' AND read_state='no';",
             user_two_name);
    // 执行查询并处理结果
    ret = database_query(db, qquerySql);
    printdatabase(ret);
    int qunliao = 0;
    if (ret.row > 0 && ret.col > 0) {
        qunliao = ret.row;
    }
    // 构造响应消息
    char response[512];
    snprintf(response, sizeof(response), "siliao=%d qunliao=%d", siliao, qunliao);

    // 发送响应给客户端
    MSG resp_msg = {0};
    resp_msg.type = _view_chat_noread;
    strncpy(resp_msg.data, response, sizeof(resp_msg.data) - 1);
    resp_msg.data[sizeof(resp_msg.data) - 1] = '\0';
    send(fd, &resp_msg, sizeof(resp_msg), 0);

}

// 商家 查看未读消息
void view_chat_noread_shangjia(int fd,MSG msg){
     printf("%s\n",msg.data);
    //在数据库中查找 第二个用户名 为这个数据  私聊 并且 状态是未读 的
     char user_two_name[64];
    snprintf(user_two_name, sizeof(user_two_name), "商家%s", msg.data);
    // 构建查询语句  查私聊
    char querySql[512];
    snprintf(querySql, sizeof(querySql),
             "SELECT user_one_name, char_data FROM char "
             "WHERE user_two_name='%s' AND private_char='yes' AND read_state='no';",
             user_two_name);
    // 执行查询并处理结果
    RET ret = database_query(db, querySql);
    printdatabase(ret);
     int siliao = 0;
    if (ret.row > 0 && ret.col > 0) {
        siliao = ret.row;
    }
    // 构建查询语句  查群聊
    char qquerySql[512];
    snprintf(qquerySql, sizeof(qquerySql),
             "SELECT user_one_name, char_data FROM char "
             "WHERE user_two_name='%s' AND group_char_system='yes' AND read_state='no';",
             user_two_name);
    // 执行查询并处理结果
    ret = database_query(db, qquerySql);
    printdatabase(ret);
    int qunliao = 0;
    if (ret.row > 0 && ret.col > 0) {
        qunliao = ret.row;
    }
    // 构造响应消息
    char response[512];
    snprintf(response, sizeof(response), "siliao=%d qunliao=%d", siliao, qunliao);

    // 发送响应给客户端
    MSG resp_msg = {0};
    resp_msg.type = _view_chat_noread;
    strncpy(resp_msg.data, response, sizeof(resp_msg.data) - 1);
    resp_msg.data[sizeof(resp_msg.data) - 1] = '\0';
    send(fd, &resp_msg, sizeof(resp_msg), 0);
}

// 查看商品列表
void view_products(int fd ,MSG msg){
    // 构建查询所有产品的SQL语句
    char sql[256] = "SELECT * FROM product";
    RET ret = database_query(db, sql);
    printdatabase(ret);

    // 如果查询结果为空，则返回失败消息
    if (ret.row == 0) {
        msg.type = _no;
        memcpy(msg.data, "没有找到任何产品", sizeof("没有找到任何产品"));
        send(fd, &msg, sizeof(msg), 0);
        return;
    }

    // 遍历查询结果并逐条发送给客户端
    for (int i = 0; i < ret.row; i++) {
        PRODUCT product;
        product.id = atoi(ret.result[(i+1) * ret.col + 0]);
        memcpy(&product.merchant_name, ret.result [((i+1) * ret.col + 2)], sizeof(product.merchant_name));
        memcpy(&product.product_name, ret.result[((i+1) * ret.col + 3)], sizeof(product.product_name));
        product.product_val = atoi(ret.result[(i+1) * ret.col + 4]);
        product.product_num = atoi(ret.result[(i+1) * ret.col + 5]);

        // 构建消息并发送给客户端
        msg.type = _merchant_find_product;
        memcpy(msg.data, &product, sizeof(PRODUCT));
        send(fd, &msg, sizeof(msg), 0);
    }

    // 发送结束标志
    msg.type = over;
    send(fd, &msg, sizeof(msg), 0);
}

// 购买商品
void buy_product(int fd ,MSG msg){
    
    //判断输入的参数是否合理
    char productId[16]; // 产品id号
    int quantity;       //要购买的产品数量
    if (sscanf(msg.data, "%15s %d", productId, &quantity) != 2 || quantity <= 0) {
        printf("无效的商品ID或数量。\n");
        MSG response = { .type = _no };
        memcpy(response.data, "无效的商品ID或数量 ", sizeof("无效的商品ID或数量  "));
        send_msg_to_server(fd, response);
        return;
    }
    printf("接收到的购买商品信息是 %s %d \n",productId,quantity);
     //先查询商品存不存在  在product数据库
    // 检查商品是否存在，并获取商品信息
    char queryProductSql[256];
    sprintf(queryProductSql, "SELECT merchant_name, product_val, product_num ,product_name FROM product WHERE id='%s';", productId);
    RET ret = database_query(db, queryProductSql);

    if (ret.row == 0) {
        printf("商品不存在\n");
        MSG response = { .type = _no };
        memcpy(response.data, "商品不存在", sizeof("商品不存在  "));
        send_msg_to_server(fd, response);
        return;
    }
    // 假设我们只有一行结果 获取商品信息
    const char *merchantName = ret.result[ret.col]; // 第一行第一列  商家名
    int productVal = atoi(ret.result[ret.col + 1]); // 第一行第二列  产品价格
    int productNum = atoi(ret.result[ret.col + 2]); // 第一行第三列  产品数量
    char * productName = ret.result[ret.col + 3]; // 第一行第四列  产品名

    //查看用户余额足不足够 查看people数据库
    // 检查库存是否足够
    if (productNum < quantity) {
        printf("库存不足\n");
        MSG response = { .type = _no };
        memcpy(response.data, "库存不足", sizeof("库存不足  "));
        send_msg_to_server(fd, response);
        return;
    }

    //通过登录 更新的时间戳 用户名绑定的套接字 
    //反过来查找 用户名 通过用户名操作数据库（用户名唯一）  在用户账号数据库people
    // 这里简化处理，直接用fd查找绑定的用户名
    char queryUserSql[256];
    sprintf(queryUserSql, "SELECT name, value FROM people WHERE user_fd='%d';", fd);
    ret = database_query(db, queryUserSql);

    if (ret.row == 0) {
        printf("未找到对应的用户\n");
        MSG response = { .type = _no };
        memcpy(response.data, "未找到对应的用户", sizeof("未找到对应的用户  "));
        send_msg_to_server(fd, response);
        return;
    }

    const char *userName = ret.result[ret.col]; // 第一行第一列  用户名
    float balance = atof(ret.result[ret.col + 1]); // 第一行第二列 用户余额

    // 检查用户余额是否足够
    float totalCost = productVal * quantity;
    if (balance < totalCost) {
        printf("余额不足\n");
        MSG response = { .type = _no };
        memcpy(response.data, "余额不足", sizeof("余额不足 "));
        send_msg_to_server(fd, response);
        printf("余额不足 %s\n",response.data);
        return;
    }

    //都满足就操作数据库 货物数据库减库存 将购买的订单存到 订单表 user_order数据库 然后返回一个 _yes

    printf("更新用户余额\n");
    // 更新用户余额（使用用户名）
    char updateBalanceSql[256];
    sprintf(updateBalanceSql, "UPDATE people SET value=value-%.2f WHERE name='%s';", totalCost, userName);
    exec_sql(db, updateBalanceSql);

    printf("更新商品库存\n");
    // 更新商品库存
    char updateStockSql[256];
    sprintf(updateStockSql, "UPDATE product SET product_num=product_num-%d WHERE id='%s';", quantity, productId);
    exec_sql(db, updateStockSql);

    printf("插入订单记录到user_order表\n");
    // 插入订单记录到user_order表
    char insertOrderSql[512];
    sprintf(insertOrderSql, 
        "INSERT INTO user_order (user_name, product_id, merchant_name, \
        product_name, product_val, product_num, buy_state) "
        "VALUES ('%s', '%s', '%s', '%s', %d, %d, '购买');",
        userName, productId, merchantName, productName, productVal, quantity);
    exec_sql(db, insertOrderSql); 

    // 返回成功响应给客户端
    MSG response = { .type = _yes };
    memcpy(response.data, "购买成功", sizeof("购买成功  "));
    send_msg_to_server(fd, response);

}

// 查看订单
void view_orders(int fd ,MSG msg){
    //通过套接字 直接找到用户 
    // 通过fd查找绑定的用户名
    char queryUserSql[256];
    snprintf(queryUserSql, sizeof(queryUserSql), "SELECT name FROM people WHERE user_fd='%d';", fd);
    RET ret = database_query(db, queryUserSql);

    if (ret.row == 0) {
        printf("未找到对应的用户\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "未找到对应的用户");
        send_msg_to_server(fd, response);
        return;
    }

    const char *userName = ret.result[ret.col]; // 第一行第一列 用户名

    //通过用户找到 用户订单表  user_order 再通过产品id找到 产品的详细信息
    // 查询用户订单表和关联的产品信息
    char queryOrdersSql[512];
    snprintf(queryOrdersSql, sizeof(queryOrdersSql),
             "SELECT uo.product_id, p.merchant_name, p.product_name, p.product_val, uo.product_num "
             "FROM user_order AS uo JOIN product AS p ON uo.product_id = p.id "
             "WHERE uo.user_name='%s';", userName);
    RET ordersRet = database_query(db, queryOrdersSql);

    if (ordersRet.row == 0) {
        printf("该用户没有订单记录。\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "该用户没有订单记录");
        send_msg_to_server(fd, response);
        return;
    }
    // 构建订单信息字符串并逐条发送给客户端
    for (int i = 0; i < ordersRet.row; i++) {
        // 每次构建单个订单的信息字符串
        char orderInfo[256] = "";
        snprintf(orderInfo, sizeof(orderInfo),
                 "商品ID:%s, 商家名:%s, 商品名:%s, 商品价格:%s, 购买的商品数量:%s",
                 ordersRet.result[(i+1) * ordersRet.col], // 商品ID
                 ordersRet.result[(i+1) * ordersRet.col + 1], // 商家名
                 ordersRet.result[(i+1) * ordersRet.col + 2], // 商品名
                 ordersRet.result[(i+1) * ordersRet.col + 3], // 商品价格
                 ordersRet.result[(i+1) * ordersRet.col + 4]); // 购买的商品数量

        // 发送单个订单信息给客户端
        MSG response = { .type = _yes };
        strncpy(response.data, orderInfo, sizeof(response.data) - 1);
        response.data[sizeof(response.data) - 1] = '\0'; // 确保字符串终止符
        send_msg_to_server(fd, response);
    }
    // 发送结束信号 over 给客户端
    MSG endMsg = { .type = over };
    send_msg_to_server(fd, endMsg);
    
}

// 取消订单
void cancel_order(int fd ,MSG msg){
    //判断客户端发来的消息是不是合法的 通过用户发送的订单 商品名
    // 解析客户端发来的订单ID
    char orderId[16];
    strncpy(orderId, msg.data, sizeof(orderId) - 1);
    orderId[sizeof(orderId) - 1] = '\0'; // 确保字符串以null结尾
    //通过套接字fd找到用户名（唯一）
    char queryUserSql[256];
    snprintf(queryUserSql, sizeof(queryUserSql), "SELECT name FROM people WHERE user_fd='%d';", fd);
    RET ret = database_query(db, queryUserSql);
    if (ret.row == 0) {
        printf("未找到对应的用户\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "未找到对应的用户");
        send_msg_to_server(fd, response);
        return;
    }
    const char *userName = ret.result[ret.col]; // 第一行第一列 用户名

    //通过用户 和 用户的商品名 找到用户的订单 将其 购买状态设置为取消
    // 查询用户订单表中指定订单的状态
    char queryOrderSql[256];
    snprintf(queryOrderSql, sizeof(queryOrderSql),
             "SELECT product_name, product_val, product_num, buy_state "
             "FROM user_order WHERE user_name='%s' AND product_id='%s';",
             userName, orderId);
    RET orderRet = database_query(db, queryOrderSql);

    if (orderRet.row == 0) {
        printf("未找到指定的订单或订单不可取消。\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "未找到指定的订单或订单不可取消");
        send_msg_to_server(fd, response);
        return;
    }
    // 检查订单状态是否允许取消
    if (strcmp(orderRet.result[orderRet.col * orderRet.row + 3], "购买") != 0) {
        printf("订单状态不允许取消。\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "订单状态不允许取消（你还没有购买）");
        send_msg_to_server(fd, response);
        return;
    }
    // 更新订单状态为取消
    char updateOrderSql[256];
    snprintf(updateOrderSql, sizeof(updateOrderSql),
             "UPDATE user_order SET buy_cancel_state='取消', buy_state='取消' "
             "WHERE user_name='%s' AND product_id='%s';",
             userName, orderId);
    exec_sql(db, updateOrderSql);

    //更新 用户的 账户 余额
    // 更新用户的账户余额
    char updateUserBalanceSql[256];
    int productVal = atoi(orderRet.result[orderRet.col * orderRet.row + 1]); // 商品价格
    int productNum = atoi(orderRet.result[orderRet.col * orderRet.row + 2]); // 商品数量
    snprintf(updateUserBalanceSql, sizeof(updateUserBalanceSql),
             "UPDATE people SET value=value+%d WHERE name='%s';",
             productVal * productNum, userName);
    exec_sql(db, updateUserBalanceSql);

    //更新货物 表的库存
    // 更新商品库存
    char updateProductStockSql[256];
    snprintf(updateProductStockSql, sizeof(updateProductStockSql),
             "UPDATE product SET product_num=product_num+%d "
             "WHERE id='%s';",
             productNum, orderId);
    exec_sql(db, updateProductStockSql);

    // 返回成功响应给客户端
    MSG response = { .type = _yes };
    snprintf(response.data, sizeof(response.data), "订单取消成功");
    send_msg_to_server(fd, response);
}

// 评价商品
void review_product(int fd ,MSG msg){
    DEBUG("进入服务器评价商品");
    //解析数据
    CHAR *char_msg = (CHAR*)msg.data;
    //sscanf(msg->data, "%63s %63s %[^\n]", char_msg->name, char_msg->id, char_msg->data);
    // 通过fd查找绑定的用户名
    char queryUserSql[256];
    snprintf(queryUserSql, sizeof(queryUserSql), "SELECT name FROM people WHERE user_fd='%d';", fd);
    RET ret = database_query(db, queryUserSql);

    if (ret.row == 0) {
        printf("未找到对应的用户\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "未找到对应的用户");
        send_msg_to_server(fd, response);
        return;
    }
    DEBUG("评价服务器查询用户完毕");
    const char *userName = ret.result[ret.col]; // 第一行第一列 用户名


    //查看发过来的商家店铺名 和 商品是否存在 在 货物表 product数据库
    // 检查产品和商家是否存在
    char checkProductSql[256];
    snprintf(checkProductSql, sizeof(checkProductSql),
             "SELECT id FROM product WHERE id='%s' AND merchant_name='%s';",
             char_msg->id, char_msg->name);
    RET productRet = database_query(db, checkProductSql);

    if (productRet.row == 0) {
        printf("未找到对应的商品或商家\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "未找到对应的商品或商家");
        send_msg_to_server(fd, response);
        return;
    }
    DEBUG("服务器评价 查询商家完毕");
    //如果产品和商家存在就 将 商品的评价 写入到 聊天表中 
    //先通过 fd 找到 用户名 填写到 用户1 中 将 评价写入char_data 中 将 对应的 商家店铺名 和 商品 id 填入到 char 数据库表格中
    // 将评价信息写入聊天表中
    char insertReviewSql[512];
    snprintf(insertReviewSql, sizeof(insertReviewSql),
             "INSERT INTO char(user_one_name, user_one_fd, \
             user_two_name, char_data,\
              merchant_shop_name, shop_id)\
              VALUES('%s', '%d', '%s', '%s', '%s', '%s');",
             userName, fd, char_msg->name, char_msg->data, char_msg->name, char_msg->id);
    exec_sql(db, insertReviewSql);
    DEBUG("将评价写入数据库中");
    // 返回成功响应给客户端
    MSG response = { .type = _yes };
    //snprintf(response.data, sizeof(response.data), "评价已提交");
    //send_msg_to_server(fd, response);
    memcpy(response.data,"评价成功 ",sizeof("评价成功  "));
    send(fd, &response, sizeof(response), 0);
    
}

// 查看商品的评价
void view_reviews(int fd, MSG msg){
    printf("进入 服务器 查看 商品 的 评价\n");
    CHAR char_msg;
    sscanf(msg.data, "%63s %63s", char_msg.name, char_msg.id);

     // 检查产品和商家是否存在
    char checkProductSql[256];
    snprintf(checkProductSql, sizeof(checkProductSql),
             "SELECT id FROM product WHERE id='%s' AND merchant_name='%s';",
             char_msg.id, char_msg.name);
    RET productRet = database_query(db, checkProductSql);

    if (productRet.row == 0) {
        printf("未找到对应的商品或商家\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "未找到对应的商品或商家");
        send_msg_to_server(fd, response);
        return;
    }
    printf("服务器检测 产品 和商家 是否 存在 结束 （存在）\n");

    // 查询商品评价信息
    char queryReviewsSql[256];
    snprintf(queryReviewsSql, sizeof(queryReviewsSql),
             "SELECT user_one_name, char_data FROM char WHERE shop_id='%s' AND merchant_shop_name='%s';",
             char_msg.id, char_msg.name);
    RET reviewsRet = database_query(db, queryReviewsSql);

    if (reviewsRet.row == 0) {
        printf("未找到对应的评价信息\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "未找到对应的评价信息");
        send_msg_to_server(fd, response);
        return;
    }
    printf("服务器检测 查询商品评价信息 （存在）\n");

    // 构建订单信息字符串并逐条发送给客户端
    for (int i = 0; i < reviewsRet.row; i++) {
        // 每次构建单个订单的信息字符串
        char orderInfo[256] = "";
        snprintf(orderInfo, sizeof(orderInfo),
                 "用户名:%s, 评价:%s ",
                 reviewsRet.result[(i+1) * reviewsRet.col], // 用户名
                 reviewsRet.result[(i+1) * reviewsRet.col + 1] // 评价
                 ); 

        // 发送单个订单信息给客户端
        MSG response = { .type = _yes };
        strncpy(response.data, orderInfo, sizeof(response.data) - 1);
        response.data[sizeof(response.data) - 1] = '\0'; // 确保字符串终止符
        send_msg_to_server(fd, response);
    }
    // 发送结束信号 over 给客户端
    MSG endMsg = { .type = over };
    send_msg_to_server(fd, endMsg);
}

// 退货
void return_goods(int fd ,MSG msg){

}

// 咨询商家
void consult_merchant(int fd ,MSG msg){

}

// 查看个人信息
void view_personal_info(int fd ,MSG msg){
    // 通过fd查找绑定的用户信息
    char queryUserSql[256];
    snprintf(queryUserSql, sizeof(queryUserSql),
             "SELECT name, pwd, tel, flag, value, user_fd, updata_time, chat_state, return_time "
             "FROM people WHERE user_fd='%d';", fd);
    RET ret = database_query(db, queryUserSql);

    if (ret.row == 0) {
        printf("未找到对应的用户信息\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "未找到对应的用户信息");
        send_msg_to_server(fd, response);
        return;
    }

    // 构建个人信息字符串
    char profileDetails[1024] = "";
    snprintf(profileDetails, sizeof(profileDetails),
             "用户名: %s\n密码: %s\n电话: %s\n余额: %s\n",
             ret.result[0+ret.col], // 用户名
             ret.result[1+ret.col], // 密码
             ret.result[2+ret.col], // 电话
             ret.result[4+ret.col] // 余额
             ); 

    // 返回个人信息给客户端
    MSG response = { .type = _yes };
    strncpy(response.data, profileDetails, sizeof(response.data) - 1);
    response.data[sizeof(response.data) - 1] = '\0'; // 确保字符串以null结尾
    send_msg_to_server(fd, response);
}

// 编辑个人信息
void edit_personal_info(int fd ,MSG msg){
    REGIST reg;
    sscanf(msg.data, "%127s %127s %15s", reg.name, reg.pwd, reg.find);
    // 检查新用户名是否已经存在
    char checkNameSql[256];
    snprintf(checkNameSql, sizeof(checkNameSql),
             "SELECT name FROM people WHERE name='%s';", reg.name);
    RET nameRet = database_query(db, checkNameSql);

    if (nameRet.row > 0) {
        printf("用户名已存在\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "用户名已存在");
        send_msg_to_server(fd, response);
        return;
    }

    // 检查新电话号码是否已经存在
    char checkTelSql[256];
    snprintf(checkTelSql, sizeof(checkTelSql),
             "SELECT tel FROM people WHERE tel='%s';", reg.find);
    RET telRet = database_query(db, checkTelSql);

    if (telRet.row > 0) {
        printf("电话号码已存在\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "电话号码已存在");
        send_msg_to_server(fd, response);
        return;
    }

    // 更新用户信息
    char updateProfileSql[256];
    snprintf(updateProfileSql, sizeof(updateProfileSql),
             "UPDATE people SET name='%s', pwd='%s', tel='%s' WHERE user_fd='%d';",
             reg.name, reg.pwd, reg.find, fd);
    exec_sql(db, updateProfileSql);

    // 返回成功响应给客户端
    MSG response = { .type = _yes };
    snprintf(response.data, sizeof(response.data), "个人信息已成功修改");
    send_msg_to_server(fd, response);


}

// 查看余额
void check_balance(int fd ,MSG msg){
     // 查询用户的余额信息
    char queryBalanceSql[256];
    snprintf(queryBalanceSql, sizeof(queryBalanceSql),
             "SELECT value FROM people WHERE user_fd='%d';", fd);
    RET ret = database_query(db, queryBalanceSql);

    if (ret.row == 0) {
        printf("未找到对应的用户信息\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "未找到对应的用户信息");
        send_msg_to_server(fd,  response);
        return;
    }

    // 返回余额给客户端
    MSG response = { .type = _yes };
    strncpy(response.data, ret.result[ret.col], sizeof(response.data) - 1); // 用户余额
    response.data[sizeof(response.data) - 1] = '\0'; // 确保字符串以null结尾
    send_msg_to_server(fd,  response);
}

// 提现
void withdraw_money(int fd ,MSG msg){
    // 获取提现金额
    int amount = atoi(msg.data);

    // 检查用户余额是否足够
    char queryBalanceSql[256];
    snprintf(queryBalanceSql, sizeof(queryBalanceSql),
             "SELECT value FROM people WHERE user_fd='%d';", fd);
    RET balanceRet = database_query(db, queryBalanceSql);

    if (balanceRet.row == 0 || atoi(balanceRet.result[balanceRet.col]) < amount) {
        printf("余额不足或用户信息不存在\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "余额不足或用户信息不存在");
        send_msg_to_server(fd,  response);
        return;
    }

    // 更新用户余额
    char updateBalanceSql[256];
    snprintf(updateBalanceSql, sizeof(updateBalanceSql),
             "UPDATE people SET value=value-%d WHERE user_fd='%d';", amount, fd);
    exec_sql(db, updateBalanceSql);

    // 返回成功响应给客户端
    MSG response = { .type = _yes };
    snprintf(response.data, sizeof(response.data), "提现成功");
    send_msg_to_server(fd,  response);
}

// 修改密码
void change_password(int fd ,MSG msg){
    // 获取旧密码和新密码
    char oldPwd[128], newPwd[128];
    sscanf(msg.data, "%127s %127s", oldPwd, newPwd);

    // 验证旧密码是否正确
    char verifyPwdSql[256];
    snprintf(verifyPwdSql, sizeof(verifyPwdSql),
             "SELECT pwd FROM people WHERE user_fd='%d' AND pwd='%s';", fd, oldPwd);
    RET pwdRet = database_query(db, verifyPwdSql);

    if (pwdRet.row == 0) {
        printf("旧密码错误\n");
        MSG response = { .type = _no };
        snprintf(response.data, sizeof(response.data), "旧密码错误");
        send_msg_to_server(fd,  response);
        return;
    }

    // 更新用户密码
    char updatePwdSql[256];
    snprintf(updatePwdSql, sizeof(updatePwdSql),
             "UPDATE people SET pwd='%s' WHERE user_fd='%d';", newPwd, fd);
    exec_sql(db, updatePwdSql);

    // 返回成功响应给客户端
    MSG response = { .type = _yes };
    snprintf(response.data, sizeof(response.data), "密码已成功修改");
    send_msg_to_server(fd,  response);
}

// 充值账户
void recharge_account(int fd ,MSG msg){
    // 获取充值金额
    int amount = atoi(msg.data);

    // 更新用户余额
    char updateBalanceSql[256];
    snprintf(updateBalanceSql, sizeof(updateBalanceSql),
             "UPDATE people SET value=value+%d WHERE user_fd='%d';", amount, fd);
    exec_sql(db, updateBalanceSql);

    // 返回成功响应给客户端
    MSG response = { .type = _yes };
    snprintf(response.data, sizeof(response.data), "充值成功");
    send_msg_to_server(fd, response);
}